package com.dm.cloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.dm.cloud.api.service.IAccountService;
import com.dm.cloud.common.R;
import com.dm.cloud.api.dto.Account;
import com.dm.cloud.databases.mutimysql.DataBaseConst;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

@Log4j2
@RestController
@RequestMapping("account")
public class AccountController {

    @Autowired
    private IAccountService accountService;

    /**
     * 自定义限流
     * 返回值和参数要和目标函数一致
     * */
    public R<Account> searchFallback(String accountCode, BlockException ex) {
        log.error("服务异常",ex);
//        prohibit
        return R.failure(accountCode + "查询被限流！");
    }

    /**
     * 自定义熔断异常
     * 返回值和参数要跟目标函数一样
     */
    public R<Account> fallbackHandler(String accountCode){
        return R.failure(0,"服务被熔断了，不要调用!");
    }

    @GetMapping("/search/{accountCode}")
    @SentinelResource(value="accountSearch",blockHandler = "searchFallback",fallback="fallbackHandler" )
    public R<Account> search(@PathVariable("accountCode") String accountCode){
        log.info("get account detail,accountCode is :{}",accountCode);
        R<Account> result = accountService.selectByCode(accountCode, DataBaseConst.CLOUD_BUSINESS);
        return result;
    }

    @PostMapping("/insert")
    @SentinelResource(value="accountInsert",blockHandler = "defaultFallback")
    public R<Long> insert(@RequestBody Account account){
        log.info("insert info :{}",account);
        return accountService.insert(account, DataBaseConst.CLOUD_BUSINESS);
    }

    @PostMapping("/update")
    public R<Long> update(@RequestBody Account account){
        log.info("update info :{}",account);
        return accountService.updateById(account, DataBaseConst.CLOUD_BUSINESS);
    }

    @PostMapping("/delete")
    public R<Long> delete(@RequestBody Account account){
        log.info("delete info :{}",account);
        return accountService.deleteById(account, DataBaseConst.CLOUD_BUSINESS);
    }

    @GetMapping("/reduce/{accountCode}/{amount}")
    public R<Boolean> reduce(@PathVariable("accountCode") String accountCode, @PathVariable("amount") BigDecimal amount){
        log.info("reduce info :{}{}",accountCode,amount);
        return accountService.reduce(accountCode,amount, DataBaseConst.CLOUD_BUSINESS);
    }
}
